# 主要功能：调用百度搜索，并将结果返回给用户，如果用户需要查询天气，则调用function call 获取天气信息，返回给用户。
# 功能：
# 1. 接收用户输入的搜索关键词   
#     1.1 如果用户输入的是“天气”，则调用function call 获取天气信息，返回给用户。
#     1.2 如果用户输入的是其他关键词，则调用百度搜索API，获取搜索结果，返回给用户。
# 2. 调用百度搜索API，获取搜索结果
# 3. 将搜索结果返回给用户

import os
import json
import requests
import logging
from openai import OpenAI
from baidusearch.baidusearch import search


# 初始化OpenAI客户端
client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY"),
    base_url="https://api.deepseek.com/v1"
)

# 设置OpenWeatherMap API密钥
OPENWEATHER_API_KEY = "d94892357e6b825afa1c15556492f40e"

# 从文件加载城市名称映射
def load_city_mapping():
    try:
        with open('china_cities.json', 'r', encoding='utf-8') as f:
            return json.load(f)
    except FileNotFoundError:
        logging.info("城市映射文件不存在，将使用默认映射")
        return {}
    except Exception as e:
        logging.error(f"加载城市映射失败: {e}")
        return {}


city_mapping = load_city_mapping()


def translate_chinese_to_english(city_name):
    if city_name in city_mapping:
        return city_mapping[city_name]

    try:
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": "你是一个翻译助手，将中文地名翻译成英文。"},
                {"role": "user", "content": f"请将以下中文城市名称翻译成英文，只需返回英文名称，不要解释或其他内容：{city_name}"}
            ],
            temperature=0,
        )
        translated_name = response.choices[0].message.content.strip()
        return translated_name
    except Exception as e:
        logging.error(f"翻译城市名称失败: {e}")
        return city_name


def get_current_weather(location):
    english_location = translate_chinese_to_english(location)

    base_url = "http://api.openweathermap.org/data/2.5/weather"
    params = {
        "q": english_location,
        "appid": OPENWEATHER_API_KEY,
        "units": "metric",
        "lang": "zh_cn"
    }

    try:
        response = requests.get(base_url, params=params)
        response.raise_for_status()
        weather_data = response.json()

        weather_info = {
            "location": location,
            "temperature": weather_data["main"]["temp"],
            "description": weather_data["weather"][0]["description"],
            "humidity": weather_data["main"]["humidity"],
            "wind_speed": weather_data["wind"]["speed"],
            "icon": weather_data["weather"][0]["icon"]
        }
        return json.dumps(weather_info)
    except Exception as e:
        return json.dumps({"error": f"获取天气失败: {str(e)}"})


def search_internet(query, num_results=10):
    try:
        results = search(query, num_results=num_results)
        return json.dumps(results)
    except Exception as e:
        logging.error(f"网络搜索失败: {e}")
        return json.dumps({"error": f"搜索失败: {str(e)}"})


def summarize_search_results(search_results):
    try:
        results = json.loads(search_results)
        if isinstance(results, list) and len(results) > 0:
            summaries = []
            for result in results[:3]:
                title = result.get("title", "")
                abstract = result.get("abstract", "")
                summaries.append(f"• {title}: {abstract}")
            return "\n\n".join(summaries)
        else:
            return "未找到相关搜索结果。"
    except Exception as e:
        logging.error(f"总结搜索结果失败: {e}")
        return "处理搜索结果时出错。"


def should_search_based_on_keywords(user_message):
    search_keywords = [
        "最新", "今年", "今天", "当月", "本年", "最近","新闻", "报道", "现在", "目前", "谁是", "什么是",
        "哪里", "为什么", "如何", "怎样", "多少", "多久", "时间",
        "排名", "名单", "价格", "政策", "事件", "原因", "解释"
    ]
    return any(keyword in user_message for keyword in search_keywords)


def should_search_using_llm(messages):
    search_messages = messages.copy()
    search_messages.insert(0, {
        "role": "system",
        "content": "你是一个判断助手，仅需回答'是'或'否'。用户的问题是否需要通过网络搜索获取最新信息才能更好回答？"
    })

    try:
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=search_messages,
            temperature=0,
        )

        answer = response.choices[0].message.content.strip().lower()
        return answer.startswith("是") or answer.startswith("yes")
    except Exception as e:
        logging.error(f"判断是否需要搜索失败: {e}")
        return False


def run_conversation():
    log_enabled = input("是否开启跟踪日志？(y/n): ").lower() == 'y'
    if log_enabled:
        logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

    messages = [
        {"role": "system", "content": "你是一个友好的助手，可以帮助用户查询天气信息和回答一般性问题。请用中文回答。"}
    ]

    print("助手: 你好！我可以帮你查询天气信息或回答一般性问题。")

    while True:
        user_input = input("你: ")

        if user_input.lower() in ["退出", "exit", "quit", "bye"]:
            print("助手: 再见！祝你有个愉快的一天！")
            break

        messages.append({"role": "user", "content": user_input})
        should_search = should_search_based_on_keywords(user_input) or should_search_using_llm(messages)

        if should_search:
            logging.info("通过关键词判断需要进行网络搜索")
            print("助手: 正在为你搜索相关信息...")
            search_results = search_internet(user_input, num_results=5)
            search_summary = summarize_search_results(search_results)
            print(f"搜索摘要:\n{search_summary}")
            messages.append({
                "role": "system",
                "content": "请参考以下信息进行回答：".join(search_summary)
            })
            response = client.chat.completions.create(
                model="deepseek-chat",
                messages=messages,
            )
            assistant_reply = response.choices[0].message.content
            messages.append({"role": "assistant", "content": assistant_reply})
            print(f"助手-search: {assistant_reply}")
        else:
            response = client.chat.completions.create(
                model="deepseek-chat",
                messages=messages,
                tools=[{
                    "type": "function",
                    "function": {
                        "name": "get_current_weather",
                        "description": "获取指定城市的当前天气信息",
                        "parameters": {
                            "type": "object",
                            "properties": {
                                "location": {
                                    "type": "string",
                                    "description": "城市名称英文，例如'Beijing'或'New York'"
                                }
                            },
                            "required": ["location"]
                        }
                    }
                }],
                tool_choice="auto",
            )
            response_message = response.choices[0].message
            tool_calls = response_message.tool_calls
            if tool_calls:
                messages.append(response_message)
                available_functions = {
                    "get_current_weather": get_current_weather,
                }
                for tool_call in tool_calls:
                    function_name = tool_call.function.name
                    function_to_call = available_functions[function_name]
                    function_args = json.loads(tool_call.function.arguments)
                    function_response = function_to_call(location=function_arygs["location"])
                    messages.append({
                        "tool_call_id": tool_call.id,
                        "role": "function",
                        "name": function_name,
                        "content": function_response
                    })
                second_response = client.chat.completions.create(
                    model="deepseek-chat",
                    messages=messages,
                )
                assistant_reply = second_response.choices[0].message.content
                messages.append({"role": "assistant", "content": assistant_reply})
                print(f"助手-天气: {assistant_reply}")
            else:
                assistant_reply = response_message.content
                messages.append({"role": "assistant", "content": assistant_reply})
                print(f"助手: {assistant_reply}")


if __name__ == "__main__":
    run_conversation()
